@秒灵儿
3年前 提问
1个回答

为什么栈缓冲区溢出比堆溢出更容易被攻击者利用

安全侠
3年前

栈缓冲区溢出比堆溢出更容易被攻击者利用:
利用基于栈的溢出,通常可以立即控制栈上的已保存返回地址,并因此控制当前功能返回的指令指针。
利用基于堆的溢出,通常可以将内存中的任意指针设置为任意值。

栈缓冲区溢出

在信息安全和编程中,缓冲区溢出或缓冲区溢出是一种异常,其中程序在将数据写入缓冲区时会超出缓冲区的边界并覆盖相邻的存储器位置。

缓冲区是专门用于存放数据的内存区域,通常在将程序从一个程序段移动到另一个程序段时,或者在程序之间移动。缓冲区溢出通常可能由格式错误的输入触发;如果假设所有输入都小于某个大小并且缓冲区被创建为该大小,那么产生更多数据的异常事务可能导致它写入缓冲区的末尾。如果这会覆盖相邻的数据或可执行代码,则可能导致程序行为不稳定,包括内存访问错误,错误结果和崩溃。

利用缓冲区溢出的行为是众所周知的安全漏洞。在许多系统中,程序的内存布局或整个系统都是明确定义的。通过发送旨在引起缓冲区溢出的数据,可以写入已知可保存可执行代码的区域并将其替换为恶意代码,或者有选择地覆盖与程序状态有关的数据,从而导致未被原始程序员。缓冲区在操作系统(OS)代码中很常见,因此可以进行执行权限提升的攻击并获得对计算机资源的无限制访问。 1988年着名的莫里斯蠕虫将其作为攻击技术之一。

堆溢出

简单来说:堆块中Data区存储超过了分配的大小从而覆盖后面堆块的结构。

堆块从空表中取下举例

图片

从空表中卸下一个堆块

当空闲堆块取下时,为了保持其他空闲堆块信息的完整,需要前后堆块中flink和blink信息的更改。

在快表中类似,只用前节点保存被取下节点的Flink结构即可。

但倘若我们我们通过多写入当前堆块的Data区域,使之覆盖后一个空闲堆块的Headers甚至是Flink和Blink,那么当这个空闲堆块被使用而从空表或快表中取下时,我们实际控制了相关节点的向前或向后指针,快表或空表就会认为伪造的Flink或者Blink中的地址中是空闲的堆块,从而在分配下一个空闲堆块时,向伪造的的地址写入。这样的攻击实现了任意地址写。

栈缓冲区溢出比堆溢出更容易被攻击者利用

利用基于栈的溢出,通常可以立即控制栈上的已保存返回地址,并因此控制当前功能返回的指令指针。可以将指令指针指向包含shellcode的任意地址(通常位于触发溢出的同一缓冲区内)。

利用基于堆的溢出,通常可以将内存中的任意指针设置为任意值。正常情况下,利用这种修改来控制执行流还需要采取其他步骤。此外,使堆缓冲区溢出后,渗透测试员可能无法立即实施攻击,而要依赖于影响堆内存分配的意外事件。